package com.jd.basic.service.impl;


import com.jd.basic.config.BusinessException;
import com.jd.basic.dto.SmsCodeDto;
import com.jd.basic.service.IVerifyService;
import com.jd.basic.util.SmsUtil;
import com.jd.basic.util.StrUtils;
import com.jd.basic.util.VerifyCodeUtils;
import com.jd.user.domain.User;
import com.jd.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyServiceImpl implements IVerifyService {

    @Autowired
    @Qualifier("redisTemplate")
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;

    /**
     * 获取图形验证码
     * @param key
     * @return
     */
    @Override
    public String getImageCode(String key) {
        //判断key是否为空 - 防止跳过前端页面 不输入验证码 进行下一步

        if (StringUtils.isEmpty(key)){
            throw new BusinessException("key为空");
        }
        //获取随机验证码(verifySize为验证码长度)
        String code = VerifyCodeUtils.generateVerifyCode(4);

        //将验证码存放在redis,设置为5分钟过期
        redisTemplate.opsForValue().set(key, code, 5, TimeUnit.MINUTES);

        //将验证码的值合并到图片,使用Base64编码,并返回base64编码的字符串
        return VerifyCodeUtils.verifyCode(110, 50, code);
    }

    /**
     * 发送手机验证码
     * @param smsCodeDto
     */
    @Override
    public void sendSmsCode(SmsCodeDto smsCodeDto) {
        //1.校验 - 空值校验
        String phone = smsCodeDto.getPhone();
        String imageCode = smsCodeDto.getImageCode();
        String imageCodeKey = smsCodeDto.getImageCodeKey();

        if (StringUtils.isEmpty(phone)){
            throw new BusinessException("手机号不能为空");
        }
        if (StringUtils.isEmpty(imageCodeKey)){
            throw new BusinessException("请刷新页面重新获取图形验证码");
        }
        if (StringUtils.isEmpty(imageCode)){
            throw new BusinessException("验证码不能为空");
        }

        //2.校验 — 图形验证码校验
        //2.1 校验图形验证码是否过期
        //使用get方法通过key值获取验证码的值Value
        Object imageCodeValue = redisTemplate.opsForValue().get(imageCodeKey);
        if (imageCodeValue == null){
            throw new BusinessException("图形验证码过期,请重新获取");
        }
        //3. 校验图形验证码是否正确
        if (!imageCodeValue.toString().equalsIgnoreCase(imageCode)){
            throw new BusinessException("验证码错误,请重新输入");
        }
        //4.校验手机号是否注册
        User user = userMapper.loadByPhone(phone);
        if (user != null){
            throw new BusinessException("该手机号已注册,请直接登录");
        }
        //5.获取手机验证码,判断是否过期 9527:1233555555 时间戳
        Object redisSmsCode = redisTemplate.opsForValue().get("register:" + phone);
        System.out.println(redisSmsCode);
        String code = null;
        if (redisSmsCode == null){//第一次发送,或者验证码过期了
            //过期了就使用新的验证码
            code = StrUtils.getComplexRandomString(6); //调用工具包获取新的验证码
            System.out.println(code);
        } else {
            //没有过期
            //验证是否过了重发时间
            //以前保存的时间
            long redisTime = Long.parseLong(redisSmsCode.toString().split(":")[1]);
            //[1]拿第二个>>>>>注释7. redisTemplate.opsForValue().set("register:"+phone,code+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);
            //value值由于code+":"+System.currentTimeMillis()组成
            //现在的时间
            long nowTime = System.currentTimeMillis();
            //6.没有过期 - 判断是否过了重新发送的时间
            if ((nowTime - redisTime) < 1*60*1000){ //没有过重发时间
                throw new BusinessException("请勿重复发送验证码");

            } else {
                //没有过期就用以前的验证码
                code = redisSmsCode.toString().split(":")[0];

            }
        }
        //7.将验证码存入redis
        //redis存值格式：key[register:18708146200] : value[code:time]
        //刷新了过期时间
        redisTemplate.opsForValue().set("register:"+phone,code+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);

        //8.调用StrUtils发送短信
        //SmsUtil.sendSms(phone,"手机验证码为：" + code + ",请在3分钟内使用!!!");
        System.out.println("手机验证码为：" + code + ",请在3分钟内使用!!!");

    }

    /**
     * 微信 - 生成手机验证码 - 绑定手机号
     * @param smsCodeDto
     */
    @Override
    public void binderSmsCode(SmsCodeDto smsCodeDto) {
        String phone = smsCodeDto.getPhone();
        //1.判断空值,确认该手机号是否已经注册
        if (StringUtils.isEmpty(phone)) {
            throw new BusinessException("该手机号已注册,请使用其它手机号");
        }
        //5.获取手机验证码,判断是否过期 9527:1233555555 时间戳
        Object redisSmsCode = redisTemplate.opsForValue().get("register:" + phone);
        String code = null;
        if (redisSmsCode == null){//第一次发送,或者验证码过期了
            //过期了就使用新的验证码
            code = StrUtils.getComplexRandomString(6); //调用工具包获取新的验证码
        } else {
            //没有过期
            //验证是否过了重发时间
            //以前保存的时间
            long redisTime = Long.parseLong(redisSmsCode.toString().split(":")[1]);
            //[1]拿第二个>>>>>注释7. redisTemplate.opsForValue().set("register:"+phone,code+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);
            //value值由于code+":"+System.currentTimeMillis()组成
            //现在的时间
            long nowTime = System.currentTimeMillis();
            //6.没有过期 - 判断是否过了重新发送的时间
            if ((nowTime - redisTime) < 1*60*1000){ //没有过重发时间
                throw new BusinessException("请勿重复发送验证码");

            } else {
                //没有过期就用以前的验证码
                code = redisSmsCode.toString().split(":")[0];

            }
        }
        //7.将验证码存入redis
        //redis存值格式：key[register:18708146200] : value[code:time]
        //刷新了过期时间
        redisTemplate.opsForValue().set("register:"+phone,code+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);

        //8.调用StrUtils发送短信
        //SmsUtil.sendSms(phone,"手机验证码为：" + code + ",请在3分钟内使用!!!");
        System.out.println("手机验证码为：" + code + ",请在3分钟内使用!!!");

    }
}
